#include "SQList.h"
void SLInit(SL* ps)
{
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
void SLDestroy(SL* ps)
{
	assert(ps);
	free(ps->a);//ps->a是动态分配的，一定要释放掉，避免内存泄漏
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
void SLCheckCapacity(SL* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)//这里就涵盖了两种情况：1.列表非空但已满，2.列表为空
	{
		int capacity_tmp;
		if (ps->capacity == 0)
		{
			capacity_tmp = INIT_CAPACITY;
		}
		else
		{
			capacity_tmp = 2 * ps->capacity;
		}
		SLDataType* a_tmp = (SLDataType*)realloc(ps->a, capacity_tmp * sizeof(SLDataType));//避免出现分配失败，原指针丢失的情况
		if (a_tmp)
		{
			ps->a = a_tmp;
			ps->capacity = capacity_tmp;
		}
		else
		{
			perror("申请失败");
			exit(1);
		}
	}
}
void SLPrint(SL* ps)
{
	assert(ps);
	int size = ps->size;
	int i;
	for (i = 0; i < size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}
void SLPopBack(SL* ps)//说起来这个和Steam删东西的方式就是类似的，都是把某块空间放出去让系统自由使用，然后认为这里已经没有有效数据了。毕竟物理内存是不会少的
{
	assert(ps);
	if (ps->size)
		ps->size--;
	else
		exit(1);
}
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	memmove(ps->a + 1, ps->a, ps->size * sizeof(SLDataType));//自己写循环挪数据实在麻烦，还是用现有的函数吧（然而填第三个参数的时候也挺伤神）
	ps->a[0] = x;
	ps->size++;
}

void SLPopFront(SL* ps)
{
	assert(ps);
	if (ps->size)
	{
		memmove(ps->a, ps->a + 1, (ps->size - 1) * sizeof(SLDataType));
		ps->size--;
	}
	else
	{
		exit(1);
	}
}
//pos代表下标，而非第几个
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps->a);
	assert(pos >= 0 && pos <= ps->size);//考虑pos==ps->size的情况就是尾插
	SLCheckCapacity(ps);
	memmove(ps->a + pos + 1, ps->a + pos, (ps->size - pos) * sizeof(SLDataType));
	ps->a[pos] = x;
	ps->size++;
}
void SLErase(SL* ps, int pos)
{
	assert(ps->a);
	assert(pos >= 0 && pos < ps->size);//而尾删就不能让pos等于ps->size了
	memmove(ps->a + pos, ps->a + pos + 1, (ps->size - pos - 1) * sizeof(SLDataType));
	ps->size--;
}
int SLFind(SL* ps, SLDataType x)//返回的是与参数x匹配元素中最小的下标值
{
    assert(ps->a);
	int i;
	for (i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}